#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define THRESHOLD 32

typedef struct UsrInfo{ 
    int id;
    char name[20];
    char gender[10];
    int age;
    int step;
    struct UsrInfo *next;
}UsrInfo;

typedef struct relation {
    int id1, id2;
    int familiar;
    struct relation *next;
}Relation;

typedef struct buffer {
    int buflen;
    char msg[THRESHOLD];
    int id;
    struct buffer *next;
}Buffer;

UsrInfo *usrroot = NULL;   //Set the user structure head node to null
Relation *relroot = NULL;  //Set the relation structure head node to null
Buffer *bufroot = NULL;    //Set the buffer header node to null

int addUsr( UsrInfo *usrroot, int id, char *name, char *gender, int age, int step) {
    if (usrroot == NULL) {
        return 1;
    }
    UsrInfo *p = usrroot;
    while(p) {
        if (p->id == id)
            return 2;
        if (p->next == NULL) {
            UsrInfo *node = (UsrInfo *)malloc(sizeof(UsrInfo));
            node->id = id;
            strcpy(node->name, name);
            strcpy(node->gender, gender);
            node->age = age;
            node->step = step;
            node->next = NULL;
            p->next = node;
            break;
        }
        p = p->next;
    }
    Buffer *buf = bufroot;
    while(buf) {
        if (buf->id == id ) {
            buf->buflen = 0;
            break;
        }
        if (buf->next == NULL) {
            Buffer *node = (Buffer *)malloc(sizeof(Buffer));
            node->id = id;
            node->buflen = 0;
            node->next = NULL;
            buf->next = node;
            break;
        }
        buf = buf->next;
    }
    return 0;
}

int addFriend( Relation *relroot, int id1, int id2, int familiar) {
    UsrInfo *p = usrroot;
    int value = 0;//value: judge whether the id1 and id2 exist 
    while(p) {
        if( p->id == id1 || p->id == id2) value++;
        p = p->next;
    }
    if (value != 2) return 1;
    Relation *q = relroot;
    while(q) {
        if ( (q->id1 == id1 && q->id2 ==id2) || (q->id1 == id2 && q->id2 == id1) ) return 2;
        if (q->next == NULL) {
            Relation *node = (Relation *)malloc(sizeof(Relation));
            node->id1 = id1;
            node->id2 = id2;
            node->familiar = familiar;
            node->next = NULL;
            q->next = node;
            break;
        }
        q = q->next;
    }
    return 0;
}

void printSteps(UsrInfo *usrroot) {
    int num = 0;
    UsrInfo *p = usrroot->next;
    while(p){
        p = p->next;
        num++;
    }
    char name[num][10],s[20];
    int step[num];
    int m = 0, temp;
    for (p = usrroot->next; p; p = p->next) {
        strcpy(name[m], p->name);
        step[m] = p->step;
        m++;
    }
    for (int i=0; i<num-1; i++) {
        for(int j=0; j<num-i-1; j++) {
            if( step[j] < step[j+1]) {
                temp = step[j];
                step[j] = step[j+1];
                step[j+1] = temp;
                strcpy(s, name[j]);
                strcpy(name[j], name[j+1]);
                strcpy(name[j+1], s);
            }
        }
    }
    for (int i=0; i<num; i++) {
        printf("%d:\t%s\t%d\n", i+1, name[i], step[i]);
    }
}

void sendMsg(UsrInfo *usrroot, Relation *relroot, Buffer *bufroot, int id1, int id2, char *msg) {
    UsrInfo *p = usrroot;
    int value = 0;
    while(p) {
        if (p->id == id1 || p->id == id2) value++;
        p = p->next;
    }
    if (value != 2) {
        return;
    }
    Relation *q = relroot;
    while(q) {
        if ( (q->id1 == id1 && q->id2 == id2) || (q->id1 == id2 && q->id2 == id1)) break;
        q = q->next;
    }
    if (q == NULL) return;//If the friendship does not exist, return.
    Buffer *p2 = bufroot;
    while(p2) {
        if (p2->id == id2) {
            int msglen = strlen(msg);        
            if (msglen + p2->buflen > THRESHOLD) {
                for (int i=0; i<p2->buflen; i++) {
                    printf("%c",p2->msg[i]);
                }
                printf("%s\n",msg);
                p2->buflen = 0;
            } else {
                strcpy(p2->msg + p2->buflen, msg);
                p2->buflen += msglen;
            }
            break;
        }
        p2 = p2->next;
    }
}

int main(int argc, char *argv[])
{
    int judge = 0, r = 1;
    usrroot = (UsrInfo *)malloc(sizeof(UsrInfo));
    relroot = (Relation *)malloc(sizeof(Relation));
    bufroot = (Buffer *)malloc(sizeof(Buffer));
    int select = 0;
    while(r) {
        scanf("%d\n",&select);
        switch (select) {
            case 1: {
                UsrInfo usrInfo;
                scanf("%d%s%s%d%d",&usrInfo.id, usrInfo.name, usrInfo.gender, &usrInfo.age, &usrInfo.step);
                judge = addUsr(usrroot, usrInfo.id, usrInfo.name, usrInfo.gender, usrInfo.age,usrInfo.step);
                if(judge) printf("The added user already exists\n");
                else printf("Success!\n");
                break;
            } case 2: {
                int id1, id2, familiar;
                scanf("%d%d%d",&id1,&id2,&familiar);
                judge = addFriend(relroot, id1, id2, familiar);
                if (judge) printf("User does not exist!\n");
                else printf("Success!");
                break;
            } case 3: {
                int id1, id2;
                char msg[100] = {0};
                scanf("%d%d",&id1, &id2);
                scanf("%s",msg);
                sendMsg(usrroot, relroot, bufroot, id1, id2, msg);
                break;
            } case 4:
                printSteps(usrroot);
                break;
            default: break;
        }
        scanf("%d",&r);
    }
}